waitqueue: Reorder prepare_to_wait() so that vcpu is definitely on the
authorKeir Fraser <keir@xen.org>
Thu, 24 Nov 2011 15:49:25 +0000 (15:49 +0000)
committerKeir Fraser <keir@xen.org>
Thu, 24 Nov 2011 15:49:25 +0000 (15:49 +0000)
queue on exit, even after a wakeup.

Otherwise, when we go round the loop in wait_event(), we may not
actually sleep after the first iteration, as we do not put ourselves
back on the queue on wakeup.

Signed-off-by: Keir Fraser <keir@xen.org>
xen/common/wait.c

index cf515b1aee8f90defa5926177a1a7258e4c6bc6b..b125dc5be2c98d8c46dee962a527b7fd67ba993a 100644 (file)
@@ -107,6 +107,8 @@ static void __prepare_to_wait(struct waitqueue_vcpu *wqv)
 {
     char *cpu_info = (char *)get_cpu_info();
 
+    ASSERT(wqv->esp == 0);
+
     asm volatile (
 #ifdef CONFIG_X86_64
         "push %%rax; push %%rbx; push %%rcx; push %%rdx; push %%rdi; "
@@ -173,14 +175,13 @@ void prepare_to_wait(struct waitqueue_head *wq)
     struct waitqueue_vcpu *wqv = curr->waitqueue_vcpu;
 
     ASSERT(!in_atomic());
-    ASSERT(list_empty(&wqv->list));
+    __prepare_to_wait(wqv);
 
+    ASSERT(list_empty(&wqv->list));
     spin_lock(&wq->lock);
     list_add_tail(&wqv->list, &wq->list);
     vcpu_pause_nosync(curr);
     spin_unlock(&wq->lock);
-
-    __prepare_to_wait(wqv);
 }
 
 void finish_wait(struct waitqueue_head *wq)